package com.yeskery.nut.transaction;

import com.yeskery.nut.bean.ApplicationContext;
import com.yeskery.nut.bean.FactoryBeanRegister;
import com.yeskery.nut.bean.NoSuchBeanException;

import javax.sql.DataSource;

/**
 * 事务注册器
 * @author Yeskery
 * 2023/7/24
 */
public class TransactionRegistry {

    /** 应用上下文 */
    private final ApplicationContext applicationContext;

    /** 事务管理器 */
    private volatile TransactionManager transactionManager;

    /**
     * 构建事务注册器
     * @param applicationContext 应用上下文
     */
    public TransactionRegistry(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    /**
     * 获取事务管理器
     * @return 事务管理器
     */
    public TransactionManager getTransactionManager() {
        if (transactionManager == null) {
            synchronized (TransactionRegistry.class) {
                if (transactionManager == null) {
                    try {
                        transactionManager = applicationContext.getBean(TransactionManager.class);
                    } catch (NoSuchBeanException e) {
                        TransactionManager defaultTransactionManager = new DefaultTransactionManager((DataSource) null);
                        ((FactoryBeanRegister) applicationContext).registerBean(TransactionManager.DEFAULT_TRANSACTION_MANAGER_NAME,
                                defaultTransactionManager, TransactionManager.class, DefaultTransactionManager.class);
                        transactionManager = defaultTransactionManager;
                        TransactionManagerHolder.setTransactionManager(transactionManager);
                    }
                }
            }
        }
        return transactionManager;
    }

    /**
     * 设置事务管理器
     * @param transactionManager 事务管理器
     */
    public void setTransactionManager(TransactionManager transactionManager) {
        if (transactionManager == null) {
            throw new TransactionException("TransactionManager Can Not Be Null.");
        }
        if (this.transactionManager != null) {
            throw new TransactionException("TransactionManager Already Initialized.");
        } else {
            synchronized (TransactionRegistry.class) {
                if (this.transactionManager == null) {
                    ((FactoryBeanRegister) applicationContext).registerBean(TransactionManager.DEFAULT_TRANSACTION_MANAGER_NAME,
                            transactionManager, TransactionManager.class);
                    this.transactionManager = transactionManager;
                    TransactionManagerHolder.setTransactionManager(transactionManager);
                } else {
                    throw new TransactionException("TransactionManager Already Initialized.");
                }
            }
        }
    }
}
